/*
  从浏览器输入一个网址，按下回车到最终页面渲染完成，一共发生了什么？
    1. 判断网址是否合法
    
    2. 判断是否命中强制缓存
      如果命中，直接读取缓存资源使用，跳到第7步
      如果没有命中，下一步

    3. DNS解析（DNS查询）：将域名地址解析成ip地址
      4个缓存，1个递归查询
        浏览器DNS缓存
        计算机DNS缓存
        路由器DNS缓存
        网络运营商DNS缓存

        根域名服务器递归查询
          www.a.b.c.com -> .com -> c.com -> b.c.com -> a.b.c.com -> www.a.b.c.com
    
    4. TCP连接（TCP三次握手）
      第一次握手：客户端发起，服务器接受，服务器确保客户端发送能力正常
      第二次握手：服务器发起，客户端接受，客户端确保服务器收发能力都正常
      第三次握手：客户端发起，服务器接受，服务器确保客户端接受能力正常
          
      为什么需要三次握手：确保双方（客户端和服务器）收发（接受数据和发送数据）能力正常

    5. 发送请求：客户端发送请求报文给服务器
      请求报文内容：
        请求首行：请求地址、请求方式
        请求头：
          token: xxx
          connection: keep-alive
          content-type: application/json
        空行
        请求体
          一般放POST/PUT请求参数
        
    6. 接受响应：服务器处理请求，将响应报文发送给客户端
      响应报文：
        响应首行：响应状态码 1xx 2xx 3xx 4xx 5xx
        响应头：
          cache-control: max-age=1111 强制缓存
          etag 协商缓存
          last-modified 协商缓存
          access-control-allow-origin: * 解决跨域方案：cors
        空行
        响应体

    7. 解析渲染（浏览器如何渲染页面？）
      遇到HTML代码，调用HTML解析器，将HTML元素解析DOM树
      遇到CSS代码，调用CSS解析器，将其解析成CSSOM树
      遇到JS代码，调用JS解析器（V8引擎），解析JS代码，此时会阻塞渲染
      将DOM树和CSSOM树合成一个render（渲染）树
      根据render树，布局（layout：计算元素的大小位置等），渲染（paint：将颜色绘制上去）
      后面当再执行JS代码时，可能会操作DOM和CSS，此时就会重新生成DOM树和CSSOM树，
      重新DOM树和CSSOM树合成一个render（渲染）树，重排和重绘

      减少页面重排和重绘的措施：
        1. 尽量不要操作DOM
        2. 将多次DOM操作变成一次（innerHTMl，fragment）
        3. 使用opacity隐藏元素（不用重排，直接重绘，性能更好）
    
    8. TCP断开链接（TCP四次挥手）
      第一次挥手：客户端发起，服务器接受，客户端告诉服务器，数据发送完了
      第二次挥手：服务器发起，客户端接受，服务器告诉服务器，数据接受完了
      第三次挥手：服务器发起，客户端接受，服务器告诉服务器，数据发送完了
      第四次挥手：客户端发起，服务器接受，客户端告诉服务器，数据接受完了
        客户端等一段时间会自动断开链接，服务器接受到第四次挥手就会断开链接

      为什么需要TCP四次挥手？因为TCP是全双工协议（接受能力和发送能力），都需要断开需要4次

    https://www.yuque.com/xpromise/interview/fomgci9679lqskx5#9ad8bce4
*/
